<template>
  <div class="dashboard">
    <!-- 数据总览卡片 -->
    <el-row :gutter="20" class="data-overview">
      <el-col :span="24">
        <el-card class="total-jobs-card">
          <template #header>
            <div class="card-header">
              <span>职位数据总览</span>
            </div>
          </template>
          <div class="total-jobs-content">
            <div class="total-number">
              <h2>{{ totalJobs }}</h2>
              <p>总职位数</p>
            </div>
            <div class="city-distribution">
              <div v-for="(count, city) in cityDistribution" :key="city" class="city-item">
                <h3>{{ count }}</h3>
                <p>{{ city }}</p>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表展示区域 -->
    <el-row :gutter="20" class="charts-container">
      <!-- 城市职位分布饼图 -->
      <el-col :span="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>城市职位分布</span>
            </div>
          </template>
          <div ref="cityPieChart" class="chart"></div>
        </el-card>
      </el-col>

      <!-- 热门职位排行榜 -->
      <el-col :span="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>热门职位排行榜</span>
            </div>
          </template>
          <div ref="hotPositionsChart" class="chart"></div>
        </el-card>
      </el-col>

      <!-- 城市薪资对比图 -->
      <el-col :span="24">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>城市薪资对比</span>
            </div>
          </template>
          <div ref="salaryChart" class="chart"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import axios from 'axios'
import { ElMessage } from 'element-plus'

// 数据
const totalJobs = ref(0)
const cityDistribution = ref({})
const citiesData = ref([])

// 图表实例
let cityPieChartInstance = null
let hotPositionsChartInstance = null
let salaryChartInstance = null

// 图表DOM引用
const cityPieChart = ref(null)
const hotPositionsChart = ref(null)
const salaryChart = ref(null)

// 获取职位总数数据
const fetchTotalJobs = async () => {
  try {
    const response = await axios.get('http://localhost:8081/api/overview/total_jobs')
    if (response.data.code === 200) {
      totalJobs.value = response.data.data.totalJobs
      cityDistribution.value = response.data.data.cityDistribution
    }
  } catch (error) {
    ElMessage.error('获取职位总数数据失败')
  }
}

// 获取城市职位数据
const fetchCitiesData = async () => {
  try {
    const response = await axios.get('http://localhost:8081/api/overview/summary')
    if (response.data.code === 200) {
      citiesData.value = response.data.data.cities
      initCharts()
    }
  } catch (error) {
    ElMessage.error('获取城市职位数据失败')
  }
}

// 初始化城市职位分布饼图
const initCityPieChart = () => {
  if (!cityPieChart.value) return
  
  cityPieChartInstance = echarts.init(cityPieChart.value)
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left'
    },
    series: [
      {
        type: 'pie',
        radius: '50%',
        data: Object.entries(cityDistribution.value).map(([city, count]) => ({
          name: city,
          value: count
        })),
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  }
  cityPieChartInstance.setOption(option)
}

// 初始化热门职位排行榜
const initHotPositionsChart = () => {
  if (!hotPositionsChart.value) return

  // 合并所有城市的热门职位数据
  const positionData = {}
  citiesData.value.forEach(city => {
    city.hotPositions.forEach(position => {
      if (!positionData[position.name]) {
        positionData[position.name] = 0
      }
      positionData[position.name] += position.count
    })
  })

  // 转换为数组并排序
  const sortedPositions = Object.entries(positionData)
    .map(([name, count]) => ({ name, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 10)

  hotPositionsChartInstance = echarts.init(hotPositionsChart.value)
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'value'
    },
    yAxis: {
      type: 'category',
      data: sortedPositions.map(item => item.name)
    },
    series: [
      {
        name: '职位数量',
        type: 'bar',
        data: sortedPositions.map(item => item.count)
      }
    ]
  }
  hotPositionsChartInstance.setOption(option)
}

// 初始化城市薪资对比图
const initSalaryChart = () => {
  if (!salaryChart.value) return

  salaryChartInstance = echarts.init(salaryChart.value)
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['平均薪资']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: citiesData.value.map(city => city.name)
    },
    yAxis: {
      type: 'value',
      name: '薪资 (k)',
      axisLabel: {
        formatter: '{value}k'
      }
    },
    series: [
      {
        name: '平均薪资',
        type: 'bar',
        data: citiesData.value.map(city => parseFloat(city.avgSalary))
      }
    ]
  }
  salaryChartInstance.setOption(option)
}

// 初始化所有图表
const initCharts = () => {
  initCityPieChart()
  initHotPositionsChart()
  initSalaryChart()
}

// 处理窗口大小变化
const handleResize = () => {
  cityPieChartInstance?.resize()
  hotPositionsChartInstance?.resize()
  salaryChartInstance?.resize()
}

onMounted(() => {
  fetchTotalJobs()
  fetchCitiesData()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  cityPieChartInstance?.dispose()
  hotPositionsChartInstance?.dispose()
  salaryChartInstance?.dispose()
})
</script>

<style scoped>
.dashboard {
  padding: 20px;
}

.data-overview {
  margin-bottom: 24px;
}

.total-jobs-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
  border: none;
  border-radius: 16px;
  overflow: hidden;
}

:deep(.total-jobs-card .el-card__header) {
  background: rgba(255, 255, 255, 0.1);
  border-bottom: none;
  padding: 16px 20px;
}

:deep(.total-jobs-card .card-header span) {
  color: #fff;
  font-size: 18px;
  font-weight: 600;
}

.total-jobs-content {
  padding: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.total-number {
  text-align: center;
}

.total-number h2 {
  font-size: 48px;
  margin: 0;
  font-weight: 700;
  background: linear-gradient(135deg, #fff 0%, rgba(255, 255, 255, 0.8) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.total-number p {
  margin: 8px 0 0;
  font-size: 16px;
  opacity: 0.8;
}

.city-distribution {
  display: flex;
  gap: 24px;
}

.city-item {
  text-align: center;
  padding: 12px 24px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.city-item h3 {
  font-size: 24px;
  margin: 0;
  font-weight: 600;
}

.city-item p {
  margin: 4px 0 0;
  font-size: 14px;
  opacity: 0.8;
}

.charts-container {
  margin-bottom: 24px;
}

.chart-card {
  height: 100%;
  border-radius: 16px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.chart-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

:deep(.chart-card .el-card__header) {
  background: #fff;
  border-bottom: 1px solid #ebeef5;
  padding: 16px 20px;
}

:deep(.chart-card .card-header span) {
  font-size: 16px;
  font-weight: 600;
  color: #2c3e50;
}

.chart {
  height: 400px;
  padding: 20px;
}

:deep(.el-card__body) {
  padding: 0;
}

:deep(.el-row) {
  margin: 0 -12px;
}

:deep(.el-col) {
  padding: 0 12px;
}
</style> 